#!/usr/bin/python3
# -*- encoding:utf-8 -*-
# author: king
# create date time: 2024/4/22 下午9:59


import os
import sys
import copy
import traceback
import openpyxl
from loguru import logger
from openpyxl.utils import get_column_letter


class CopySourceStyle(object):
    """
    保留原样式的复制
    """

    def __init__(self, source_path, target_path):
        self.source_path = source_path
        self.target_path = target_path

        self.source_filename = os.path.basename(self.source_path)

        self.source_workbook = None
        self.target_workbook = None

    def open_file(self):
        """
        :return:
        :author: king
        :create date time: 2024/4/22 下午10:03
        """
        self.source_workbook = openpyxl.load_workbook(self.source_path)
        self.target_workbook = openpyxl.Workbook()

        sheet_names = self.source_workbook.sheetnames

        for sheet_name in sheet_names:
            logger.debug(f"{self.source_filename} 正在复制操作{sheet_name}...")

            source_sheet = self.source_workbook[sheet_name]
            target_sheet = self.target_workbook.create_sheet(sheet_name)

            # 保持相同的宽度
            self.__maintain_width(source_sheet, target_sheet)
            # 合并单元格
            self.__merged_cell(source_sheet, target_sheet)

            for ind, row in enumerate(source_sheet.iter_rows()):  # 迭代行
                for j, cell in enumerate(row):  # 遍历每一行的列
                    target_sheet.cell(ind + 1, j + 1, value=cell.value)  # 把对应的单元格值,从源文件中,重新复制到新文件的相同的未知

                    source_cell = source_sheet.cell(ind + 1, j + 1)  # 源文件单元格
                    target_cell = target_sheet.cell(ind + 1, j + 1)  # 目标文件单元格

                    target_cell.fill = copy.copy(source_cell.fill)

                    self.__copy_style(source_cell, target_cell)
        else:
            self.__save_target_file()

    def __maintain_width(self, source_sheet, target_sheet):
        """
        保持原有宽度
        :return:
        :author: king
        :create date time: 2024/4/23 下午9:56
        """
        for cell_position in source_sheet.column_dimensions:
            target_sheet.column_dimensions[cell_position].width = source_sheet.column_dimensions[cell_position].width

    def __merged_cell(self, source_sheet, target_sheet):
        """
        合并的单元格
        :return:
        :author: king
        :create date time: 2024/4/22 下午11:26
        """
        wm = list(source_sheet.merged_cells)
        if wm:
            # logger.debug([i for i in wm])  # 在源文件中找到合并单元格的坐标
            for i in wm:
                target_sheet.merge_cells(str(i))  # 合并操作,单元格坐标

    def __copy_style(self, source_cell, target_cell):
        """
        复制样式
        :return:
        :author: king
        :create date time: 2024/4/22 下午11:19
        """
        if source_cell.has_style:
            target_cell._style = copy.copy(source_cell._style)
            target_cell.font = copy.copy(source_cell.font)  # 复制字体
            target_cell.border = copy.copy(source_cell.border)  # 复制边框
            target_cell.fill = copy.copy(source_cell.fill)
            target_cell.number_format = copy.copy(source_cell.number_format)  # 复制数据格式
            target_cell.protection = copy.copy(source_cell.protection)
            target_cell.alignment = copy.copy(source_cell.alignment)  # 复制居中样式

    def __save_target_file(self):
        """
        保存目标文件
        :return:
        :author: king
        :create date time: 2024/4/22 下午11:05
        """
        if "Sheet" in self.target_workbook.sheetnames:
            del self.target_workbook["Sheet"]

        self.target_workbook.save(self.target_path)

    def execute(self):
        """
        :return:
        :author: king
        :create date time: 2024/4/22 下午10:05
        """
        try:
            self.open_file()
        except FileExistsError:
            logger.error(f"文件 {self.source_path} 不存在")
        except Exception as e:
            logger.error(traceback.format_exc())
        finally:
            self.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if all([exc_type, exc_val, exc_tb]):
            logger.error(traceback.format_exc())

        self.close()

    def close(self):
        """
        :return:
        :author: king
        :create date time: 2024/4/22 下午11:31
        """
        if self.source_workbook:
            self.source_workbook.close()

        if self.target_workbook:
            self.target_workbook.close()


def main():
    """程序入口"""
    source_path = r"E:\gitee_project\wll_note_records\Python2excel\cases\lele.xlsx"
    target_path = r"E:\gitee_project\wll_note_records\Python2excel\cases\lele_bak.xlsx"
    with CopySourceStyle(source_path, target_path) as opertion_obj:
        opertion_obj.execute()


if __name__ == "__main__":
    main()
